<html>
<head><meta charset="utf-8"><title>FnPointer trait · t-lang · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/index.html">t-lang</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html">FnPointer trait</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="197270528"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197270528" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197270528">(May 12 2020 at 12:55)</a>:</h4>
<p>So I've been kicking around a small-ish idea for a while. I finally sat down and <a href="https://hackmd.io/lse14c98S4mgkne1IGiIBQ?view">wrote up a proposal</a> that I wanted to float around:</p>
<h1>Summary</h1>
<p>Create a <code>FunctionPointer</code> trait that is "fundamental" (in the coherence sense) and built-in to the compiler. It is automatically implemented for all <code>fn</code> types, regardless of any other details (ABI, argument types, and so forth).</p>



<a name="197271860"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197271860" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197271860">(May 12 2020 at 13:05)</a>:</h4>
<blockquote>
<p>Will function pointers always be representable by a usize?</p>
</blockquote>
<p>If a function pointer requires more data then you can represent them as a pointer to a static "function descriptor". This is what Itanium does.</p>



<a name="197272041"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197272041" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197272041">(May 12 2020 at 13:06)</a>:</h4>
<p>I would also like to have a <code>from_usize</code> unsafe function. At the moment converting <code>usize</code> to <code>fn()</code> is not very ergonomic since we have to transmute.</p>



<a name="197273051"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197273051" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197273051">(May 12 2020 at 13:14)</a>:</h4>
<p>can we make <code>fn(foo, bar) -&gt; boo</code> the magic sugar syntax for <code>FunctionPointer</code> trait bounds? :D</p>



<a name="197273054"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197273054" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197273054">(May 12 2020 at 13:14)</a>:</h4>
<p>I've wanted this forever</p>



<a name="197273075"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197273075" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197273075">(May 12 2020 at 13:14)</a>:</h4>
<p>oh there's a proposal</p>



<a name="197273078"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197273078" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197273078">(May 12 2020 at 13:14)</a>:</h4>
<p>/me reads</p>



<a name="197273384"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197273384" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197273384">(May 12 2020 at 13:16)</a>:</h4>
<p>will this trait also be implemented for the zst function types? Since they are trivially convertable to function pointers, their impl could be doing the to-function-pointer conversion in all methods</p>



<a name="197273486"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197273486" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197273486">(May 12 2020 at 13:17)</a>:</h4>
<p>That would prevent us from adding <code>from_usize</code> though.</p>



<a name="197273610"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197273610" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197273610">(May 12 2020 at 13:18)</a>:</h4>
<p>oh hehe, right</p>



<a name="197273928"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197273928" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197273928">(May 12 2020 at 13:21)</a>:</h4>
<p>in general, the portability issue could be solved by exposing a <code>fn_ptr_size</code> type in libstd that should be used instead of <code>usize</code> and which on all current platforms is simply a newtype wrapper around <code>usize</code></p>



<a name="197273939"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197273939" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197273939">(May 12 2020 at 13:21)</a>:</h4>
<p>hm, how so? seems like you can definitely synthesize a zst with from_usize? (I presume from_usize requires specifying all arguments, right?)</p>



<a name="197273994"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197273994" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197273994">(May 12 2020 at 13:21)</a>:</h4>
<p>right, but the given <code>usize</code> could be anything else, and we can't even assert that it's a good pointer</p>



<a name="197274081"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197274081" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197274081">(May 12 2020 at 13:22)</a>:</h4>
<p>then again, that function is unsafe...</p>



<a name="197274117"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197274117" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197274117">(May 12 2020 at 13:22)</a>:</h4>
<p>I don't see how that's different from a normal function</p>



<a name="197274135"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197274135" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197274135">(May 12 2020 at 13:22)</a>:</h4>
<p>i.e. any other function pointer</p>



<a name="197274160"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197274160" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197274160">(May 12 2020 at 13:22)</a>:</h4>
<p>yea, makes sense</p>



<a name="197274201"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197274201" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197274201">(May 12 2020 at 13:23)</a>:</h4>
<p>so for zst fn types, <code>from_usize</code> is a nop</p>



<a name="197274309"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197274309" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197274309">(May 12 2020 at 13:23)</a>:</h4>
<p>That's what I would expect, I think, though one could imagine that we create tiny shims which we can call which assert the type id in debug mode or whatever</p>



<a name="197274320"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197274320" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197274320">(May 12 2020 at 13:23)</a>:</h4>
<p>seems not worth the trouble though</p>



<a name="197274326"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197274326" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197274326">(May 12 2020 at 13:24)</a>:</h4>
<p>I think this mostly won't get used for those zsts, I'd have expected the <code>as_usize</code> to be more commonly used on generic parameters</p>



<a name="197274436"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197274436" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197274436">(May 12 2020 at 13:24)</a>:</h4>
<p>also: miri can check that you use <code>from_usize</code> correctly :D</p>



<a name="197278885"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197278885" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Sebastian Malton <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197278885">(May 12 2020 at 13:54)</a>:</h4>
<p>So if I read the proposal correctly, it does not seem like it is callable form of function pointers. Namely, there doesn't seem to be a well defined type of the function that the pointer points to.</p>



<a name="197279911"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197279911" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197279911">(May 12 2020 at 14:00)</a>:</h4>
<p>It is not callable, that would be very challenging =)</p>



<a name="197279974"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197279974" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197279974">(May 12 2020 at 14:00)</a>:</h4>
<p>I'd be open <span class="user-mention" data-user-id="124288">@oli</span> to extending to <code>FnDef</code> types -- that probably makes a lot of sense, actually</p>



<a name="197280005"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197280005" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197280005">(May 12 2020 at 14:01)</a>:</h4>
<p>It argues for extending the interface to more than just <code>as_usize</code></p>



<a name="197285225"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197285225" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197285225">(May 12 2020 at 14:37)</a>:</h4>
<p><span class="user-mention" data-user-id="116009">@nikomatsakis</span> why would we need to extend beyond as_usize? AFAICT, this proposal is mainly intended to solve two goals, I guess:</p>
<ul>
<li>Abstracting over all function pointers (e.g., with a trait), likely in this case you do want to provide some facility for calling them (a downcast operation I guess)? Not sure what the use cases are. Must be unsafe, most likely.</li>
<li>Stashing a function pointer into usize fields (Atomics being the common case?).</li>
</ul>
<p>I think the first isn't really helped much by the as_usize/from_usize conversions; the latter is, though is arguably not much better than just transmuting</p>



<a name="197285462"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197285462" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197285462">(May 12 2020 at 14:39)</a>:</h4>
<p>well, actually, no, this provides a marked improvement over transmutes -- you can't do those with generic parameters</p>



<a name="197286220"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197286220" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197286220">(May 12 2020 at 14:44)</a>:</h4>
<p>technically we could provide just the trait in libstd, just like we provide <code>Future</code> and have all the extra functionality be created in user crates. You can still use <code>transmute_copy</code> so <code>as_usize</code> can be implemented in userspace</p>



<a name="197286369"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197286369" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197286369">(May 12 2020 at 14:45)</a>:</h4>
<p>ah, yeah, I forgot about transmute_copy -- I would personally I think lean towards provoding as/from_usize though, seems like the "clear use case" and better to push people away from using transmute if possible</p>



<a name="197287093"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197287093" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oli <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197287093">(May 12 2020 at 14:50)</a>:</h4>
<p>I agree with that, I just meant that if we want to not bind ourselves to <code>usize</code> as mentioned in the proposal</p>



<a name="197287434"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197287434" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> simulacrum <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197287434">(May 12 2020 at 14:52)</a>:</h4>
<p>Sure. I would be on board with returning <code>*const OpaqueFnPointer</code> too, which could be cast to usize by the user</p>



<a name="197291853"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197291853" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197291853">(May 12 2020 at 15:19)</a>:</h4>
<p>My motivations for including <code>as_usize</code> were</p>
<ul>
<li>safe alternative to transmute</li>
<li>lets you implement everything else in terms of one compiler primitive</li>
</ul>



<a name="197291881"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197291881" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197291881">(May 12 2020 at 15:19)</a>:</h4>
<p>as far as calls, I guess some kind of downcast sounds pretty plausible</p>



<a name="197291956"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197291956" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197291956">(May 12 2020 at 15:20)</a>:</h4>
<p>could probably be implemented with <code>type_id</code> intrinsics in "user space"</p>



<a name="197300764"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197300764" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197300764">(May 12 2020 at 16:19)</a>:</h4>
<p>FYI any architecture that targets Linux will have <code>usize</code>-sized function pointers because that is what <code>dlsym</code> returns. I think it is safe to rely on this always being true (the same way we assume bytes are always 8 bits)</p>



<a name="197306709"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197306709" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197306709">(May 12 2020 at 17:05)</a>:</h4>
<p>The only architecture I've worked with where this is kinda-not-true is AVR, but there the linker just uses trampolines for functions beyond 64K, so it's a non-issue in practice (at least this is what GCC does, not sure how the LLVM backend works here)</p>



<a name="197307000"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197307000" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Charles Lew <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197307000">(May 12 2020 at 17:07)</a>:</h4>
<p>I'm a little curious - why a trait here. Why not just.</p>
<div class="codehilite"><pre><span></span><code><span class="cp">#[derive(Copy, Clone, PartialEq, PartialOrd, ...)</span>
<span class="cp">struct FnPtr&lt;A, B&gt; where A: IsTuple (usize, PhantomData&lt;A&gt;, PhantomData&lt;B&gt;);</span>

<span class="cp">impl&lt;A: IsTuple, B&gt; FnPtr&lt;A, B&gt; {</span>
<span class="cp">      fn as_usize(self) -&gt; usize { self.0 }</span>
<span class="cp">}</span>
</code></pre></div>



<a name="197307457"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197307457" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197307457">(May 12 2020 at 17:10)</a>:</h4>
<p>That doesn't allow abstracting over ABIs</p>



<a name="197308458"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197308458" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Charles Lew <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197308458">(May 12 2020 at 17:18)</a>:</h4>
<p>A third generic argument will suffice?</p>



<a name="197310949"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197310949" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197310949">(May 12 2020 at 17:35)</a>:</h4>
<p>Seems more complicated than the original proposal</p>



<a name="197311872"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197311872" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Matthew Jasper <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197311872">(May 12 2020 at 17:42)</a>:</h4>
<p>More importantly is doesn't allow abstracting over bound and free lifetimes.</p>



<a name="197313128"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197313128" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197313128">(May 12 2020 at 17:50)</a>:</h4>
<p>Would this be generic over parameter types and return types? If so, I could definately use this in my os kernel, where I had a lot of pain from the type checker related to fn items and fn pointers being distinct types (trying to typecheck functions used as syscall targets, before shoving them into "heterogenous" no_mangle array to be called from assembly)</p>



<a name="197313231"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197313231" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Charles Lew <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197313231">(May 12 2020 at 17:51)</a>:</h4>
<p>Yes, i always can't remember <code>for&lt;'a&gt; fn (...)</code> is a thing... Thanks for pointing this out.</p>



<a name="197321079"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197321079" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197321079">(May 12 2020 at 18:51)</a>:</h4>
<p><span class="user-mention silent" data-user-id="211727">Jonas Schievink</span> <a href="#narrow/stream/213817-t-lang/topic/FnPointer.20trait/near/197307457">said</a>:</p>
<blockquote>
<p>That doesn't allow abstracting over ABIs</p>
</blockquote>
<p>As far as I know, our function types and traits <em>today</em> don't support abstracting over ABIs either.</p>



<a name="197324077"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197324077" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197324077">(May 12 2020 at 19:12)</a>:</h4>
<p>Indeed, but the proposed <code>FunctionPointer</code> trait would</p>



<a name="197324779"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197324779" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197324779">(May 12 2020 at 19:17)</a>:</h4>
<p>That would have to be done via magic</p>



<a name="197325756"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197325756" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jonas Schievink  [he/him] <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197325756">(May 12 2020 at 19:24)</a>:</h4>
<p>That's what's proposed, yes. The compiler provides all impls of the trait automatically.</p>



<a name="197340242"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197340242" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197340242">(May 12 2020 at 21:13)</a>:</h4>
<p><span class="user-mention silent" data-user-id="257758">Connor Horman</span> <a href="#narrow/stream/213817-t-lang/topic/FnPointer.20trait/near/197313128">said</a>:</p>
<blockquote>
<p>Would this be generic over parameter types and return types? If so, I could definately use this in my os kernel, where I had a lot of pain from the type checker related to fn items and fn pointers being distinct types (trying to typecheck functions used as syscall targets, before shoving them into "heterogenous" no_mangle array to be called from assembly)</p>
</blockquote>
<p>this might help with that, I'm not sure I fully understand the problem you were hitting</p>



<a name="197340799"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197340799" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197340799">(May 12 2020 at 21:17)</a>:</h4>
<p>I was typechecking the function against a "is_syscall&lt;S: Syscall&gt;" function. The problem was that the function item type doesn't impl Syscall, but rather the function pointer type does.</p>



<a name="197341665"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197341665" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197341665">(May 12 2020 at 21:24)</a>:</h4>
<p>Ah. That is indeed a good argument for making <code>FnDef</code> implement this trait.</p>



<a name="197341685"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197341685" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197341685">(May 12 2020 at 21:24)</a>:</h4>
<p>And it's also a nice argument for why <code>as_usize</code> is useful</p>



<a name="197341709"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197341709" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197341709">(May 12 2020 at 21:24)</a>:</h4>
<p>(because you couldn't use transmute there, since sometimes it would be zero-size, and sometimes not)</p>



<a name="197341781"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197341781" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197341781">(May 12 2020 at 21:25)</a>:</h4>
<p>it does make me kind of want a different name</p>



<a name="197342261"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197342261" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197342261">(May 12 2020 at 21:29)</a>:</h4>
<p>as_usize really wouldn't work, as I do need this statically (cast to usize isn't const).</p>



<a name="197342448"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197342448" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197342448">(May 12 2020 at 21:30)</a>:</h4>
<p>it...could be a const fn</p>



<a name="197342496"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197342496" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197342496">(May 12 2020 at 21:31)</a>:</h4>
<p>or to put another way we could provide const impls</p>



<a name="197342505"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197342505" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197342505">(May 12 2020 at 21:31)</a>:</h4>
<p>but that's a good thing to do add to the doc too</p>



<a name="197343622"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197343622" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197343622">(May 12 2020 at 21:41)</a>:</h4>
<p>I don't believe it could be const. The address of a function isn't known at compile time, its known at link-time.</p>



<a name="197348351"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197348351" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197348351">(May 12 2020 at 22:29)</a>:</h4>
<p>Hmm. That's true :)</p>



<a name="197348355"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197348355" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197348355">(May 12 2020 at 22:29)</a>:</h4>
<p>but I'm not sure that's a problem</p>



<a name="197348392"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197348392" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197348392">(May 12 2020 at 22:29)</a>:</h4>
<p>it wouldn't yield an integer whose value is known, of course</p>



<a name="197348413"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197348413" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197348413">(May 12 2020 at 22:29)</a>:</h4>
<p>but we already have integers that are pointers to things at link time etc</p>



<a name="197348465"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197348465" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197348465">(May 12 2020 at 22:30)</a>:</h4>
<p>anyway if you're able to do it at const time now, we can probably find some sol'n</p>



<a name="197361402"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197361402" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197361402">(May 13 2020 at 01:53)</a>:</h4>
<p>Possibly. A "to *const ()" would probably be easier to implement, and more useful in my case. Both could probably exist, but I can't see to_usize as being const-ifiable.</p>



<a name="197386684"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197386684" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197386684">(May 13 2020 at 09:21)</a>:</h4>
<p><span class="user-mention silent" data-user-id="124288">oli</span> <a href="#narrow/stream/213817-t-lang/topic/FnPointer.20trait/near/197274201">said</a>:</p>
<blockquote>
<p>so for zst fn types, <code>from_usize</code> is a nop</p>
</blockquote>
<p>and throws away the input? that seems suspicious?^^ (EDIT: oh, it's <code>as_usize</code> in the hackmd, that makes more sense)</p>



<a name="197387197"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197387197" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197387197">(May 13 2020 at 09:26)</a>:</h4>
<p>(deleted)</p>



<a name="197387241"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197387241" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197387241">(May 13 2020 at 09:26)</a>:</h4>
<p><span class="user-mention silent" data-user-id="116009">nikomatsakis</span> <a href="#narrow/stream/213817-t-lang/topic/FnPointer.20trait/near/197270528">said</a>:</p>
<blockquote>
<p>So I've been kicking around a small-ish idea for a while. I finally sat down and <a href="https://hackmd.io/lse14c98S4mgkne1IGiIBQ?view">wrote up a proposal</a> that I wanted to float around:</p>
<h1>Summary</h1>
<p>Create a <code>FunctionPointer</code> trait that is "fundamental" (in the coherence sense) and built-in to the compiler. It is automatically implemented for all <code>fn</code> types, regardless of any other details (ABI, argument types, and so forth).</p>
</blockquote>
<p>the links at " remove the leak-check in the compiler" and "introduced a warning about potential overlap between impls" are the same... what would be the right place to find more details about those warnings/overlapping impls? (specifically I am wondering why that is not a huge soundness hole...)</p>



<a name="197487379"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197487379" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197487379">(May 13 2020 at 22:54)</a>:</h4>
<p>Undirected Pondering:</p>
<ul>
<li>what if <code>extern "A" fn(B, C) -&gt; D</code> were sugar for some kind of <code>FnRef&lt;A, (B,C), D&gt;</code> lang item type in core?  Then people could make the trait themselves, or abstract over different <code>A</code> (including just <code>abi::Rust</code>) as they desired.  (Presumably there'd be some internal or sealed trait bound for that parameter, so we could add more later but users could not.)</li>
<li>"Things that can be representable in a usize" safe transmutes feels more general than just function pointers.  I've wanted the same for pointers and references and boxes and ... in the past as well.  So this part, to me, feels more like a <code>SafeTransmute&lt;T&gt;</code> marker trait, so we can have things like <code>i32: SafeTransmute&lt;[u8; 4]&gt;</code> or <code>isize: SafeTransmute&lt;usize&gt;</code> too.</li>
</ul>



<a name="197561821"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/213817-t-lang/topic/FnPointer%20trait/near/197561821" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/213817-t-lang/topic/FnPointer.20trait.html#197561821">(May 14 2020 at 14:18)</a>:</h4>
<p>This has the same issue I brought up, that you still can't impl something a fn-ptr type, <em>and</em> all fn-item types which have the same signature</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>